package com.weixin.engine.design.single.lazy;

/**
 * 该方式天然线程安全，是否final根据自己需要。
 * 懒汉模式-线程安全，适用于多线程
 * 在内部类被加载和初始化时 才创建实例
 * 静态内部类不会自动随着外部类的加载和初始化而初始化，它是要单独加载和初始化的。
 * 因为是在内部类加载和初始化时创建的 因此它是线程安全的
 */
public class LazyInnerSingleton {
    private LazyInnerSingleton() {
    }

    private static class Inner {
        private static final LazyInnerSingleton INSTANCE = new LazyInnerSingleton();
    }

    public static LazyInnerSingleton getInstance() {
        return Inner.INSTANCE;
    }


    /**
     * 3、破坏单例模式的方法及解决办法
     * 1、除枚举方式外, 其他方法都会通过反射的方式破坏单例,反射是通过调用构造方法生成新的对象，所以如果我们想要阻止单例破坏，可以在构造方法中进行判断，若已有实例, 则阻止生成新的实例，解决办法如下:
     *
     * 复制代码
     * 1 private SingletonObject(){
     * 2     if (instance != null){
     * 3         throw new RuntimeException("实例已经存在，请通过 getInstance()方法获取");
     * 4     }
     * 5 }
     * 复制代码
     * 2、如果单例类实现了序列化接口Serializable, 就可以通过反序列化破坏单例，所以我们可以不实现序列化接口,如果非得实现序列化接口，可以重写反序列化方法readResolve(), 反序列化时直接返回相关单例对象。
     *
     * 1   public Object readResolve() throws ObjectStreamException {
     * 2         return instance;
     * 3    }
     * 回到顶部
     * 4、总结
     * 饿汉模式
     *
     * 静态常量 简洁直观容易理解
     * 枚举 最简洁
     * 静态代码块 可以在静态块里做一些初始化的工作
     * 懒汉模式
     *
     * 单线程形式 该形式下不适用多线程，存在线程安全问题
     * 多线程形式 适用于多线程
     * 内部类形式 最简洁
     */
}